package cas;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.UnsupportedCommOperationException;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

public class SerialPortHandler {
	public SerialPort serialPort;
	private OutputStream outStream;
	private InputStream inStream;

	public String[] getPortNameList() {
		Enumeration ports = CommPortIdentifier.getPortIdentifiers();
		List<String> portList = new ArrayList<String>();
		while (ports.hasMoreElements()) {
			CommPortIdentifier port = (CommPortIdentifier) ports.nextElement();
			if (port.getPortType() == CommPortIdentifier.PORT_SERIAL) {
				portList.add(port.getName());
			}
		}
		return portList.toArray(new String[0]);
	}

	public void connect(String portName, String owner, int baudRate,
			int dataBits, int stopBits, int parity, int flowControl)
			throws IOException {
		try {
			// Obtain a CommPortIdentifier object for the port you want to open
			CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(portName);

			// Get the port's ownership
			serialPort = (SerialPort) portId.open(owner, 5000);

			// Set the parameters of the connection.
			setSerialPortParameters(baudRate, dataBits, stopBits, parity,
					flowControl);

			// Open the input and output streams for the connection. If they
			// won't
			// open, close the port before throwing an exception.
			outStream = serialPort.getOutputStream();
			inStream = serialPort.getInputStream();
		} catch (NoSuchPortException e) {
			throw new IOException(e.getMessage());
		} catch (PortInUseException e) {
			throw new IOException(e.getMessage());
		} catch (IOException e) {
			serialPort.close();
			throw e;
		}
	}

	/**
	 * \brief Disconnect the serial port
	 */
	public void disconnect() {
		if (serialPort != null) {
			try {
				// close the i/o streams.
				outStream.close();
				inStream.close();
			} catch (IOException ex) {
				// don't care
			}
			// Close the port.
			serialPort.close();
			serialPort = null;
		}
	}

	/**
	 * Get the serial port input stream
	 * 
	 * @return The serial port input stream
	 */
	public InputStream getSerialInputStream() {
		return inStream;
	}

	/**
	 * Get the serial port output stream
	 * 
	 * @return The serial port output stream
	 */
	public OutputStream getSerialOutputStream() {
		return outStream;
	}

	/**
	 * Sets the serial port parameters
	 */
	private void setSerialPortParameters(int baudRate, int dataBits,
			int stopBits, int parity, int flowControl) throws IOException {

		try {
			serialPort.setSerialPortParams(baudRate, dataBits, stopBits, parity);

			serialPort.setFlowControlMode(flowControl);
		} catch (UnsupportedCommOperationException ex) {
			ex.printStackTrace();
			throw new IOException("Unsupported serial port parameter");
		}
	}
}
